<?php

class Project_Db_Table extends Zend_Db_Table {
	public function __construct(array $config = array()) {
		$rowClass = Project_String::transformUnderlineToCase($this->_name, true);
		if (class_exists($rowClass)) {
			$this->_rowClass = $rowClass;
		}

		if (empty($this->_primary)) {
			$this->_primary = $this->_name . '_id';
		}

		parent::__construct($config);
	}

	public function getPrimaryKeyName() {
		return is_array($this->_primary) ? current($this->_primary) : $this->_primary; 
	}
	
	public function getTblName() {
		return $this->_name;
	}

	public function getSelect(array $params = array(), $join = null, $rowParams = null, $orWhere = null, $groupBy = null, $joinLeft = null) {
		$where = $this->select();
		
		$where->from(
			$this->_name
		);

		if($params && is_array($params)) {
			foreach ($params AS $key => $value) {
				if($key == 'limit' && $value !== null && is_array($value)) {
					
					if(count($value) == 2) {
						$where->limit($value[0], $value[1]);
					} else if(count($value) == 1) {
						$where->limit($value[0]);
					}
					
				} else if($key == 'order' && $value !== null) {
					
					$where->order($value);
					
				} else if($key && $value !== null) {
					
					if(is_array($value) && count($value) > 1) {
						$where->where($key . ' IN (?)', $value);
					} else {
						$where->where($key . ' = ?', $value);
					}
					
				}
			}
		}
		
		if($orWhere && is_array($orWhere)) {
			foreach ($orWhere AS $key => $value) {
				if($key && $value !== null) {
					
					if(is_array($value) && count($value) > 1) {
						$where->orWhere($key . ' IN (?)', $value);
					} else {
						$where->orWhere($key . ' = ?', $value);
					}
					
				}
			}
		}
		
		if($rowParams && is_array($rowParams)) {
			foreach ($rowParams AS $item) {
				if($item) {
					
					$where->where($item);
					
				}
			}
		}
		
		if($join && is_array($join)) {
			foreach ($join AS $key => $value) {
				if($key && $value) {
					$where->join($key, $value, array());
				}
			}
		}
		
		if($joinLeft && is_array($joinLeft)) {
			foreach ($joinLeft AS $key => $value) {
				if($key && $value) {
					$where->joinLeft($key, $value, array());
				}
			}
		}
		
		if($groupBy) {
			$where->group($groupBy);
		}

		return $where;
	}
	
	/**
	 * Возвращает объект
	 *
	 * @param array $where
	 * @param string $order
	 * @return object
	 */
	public function fetchEntry(array $where = array()) {
		return $this->fetchRow($this->getSelect($where));
	}
	
	/**
	 * Возвращает список объектов
	 *
	 * @param array $where
	 * @param array $join
	 * @param array $rowParams
	 * @return Zend_Db_Table_Rowset
	 */
	public function fetchEntries(array $where = array(), $join = null, $rowParams = null, $orWhere = null, $groupBy = null, $joinLeft = null) {
		return $this->fetchAll($this->getSelect($where, $join, $rowParams, $orWhere, $groupBy, $joinLeft));
	}
	
	/**
	 * Return User
	 *
	 * @param string $attribute
	 * @param string $value
	 * @return User
	 */
	public function getBy($attribute, $value) {
		return $this->fetchEntry(array($attribute => $value));
	}

	public function getById($id) {
		return self::getBy($this->getPrimaryKeyName(), $id);
	}

	public function getCount(array $params = array(), $rowParams = null, $join = null, $joinLeft = null, $groupBy = null) {
		$where = $this->select();
			
		$where->from($this->_name, 'COUNT(*)');

		if($params && is_array($params)) {
			foreach ($params AS $key => $value) {
				if($key == 'limit' && $value !== null && is_array($value)) {
					if(count($value) == 2) {
						$where->limit($value[0], $value[1]);
					} else if(count($value) == 1) {
						$where->limit($value[0]);
					}
				} else if($key == 'order' && $value !== null) {
					$where->order($value);
				} else if($key && $value !== null) {
					$where->where($key . ' = ?', $value);
				}
			}
		}
		
		if($rowParams && is_array($rowParams)) {
			foreach ($rowParams AS $item) {
				if($item) {
					$where->where($item);
				}
			}
		}
		
		if($join && is_array($join)) {
			foreach ($join AS $key => $value) {
				if($key && $value) {
					$where->join($key, $value, array());
				}
			}
		}
		
		if($joinLeft && is_array($joinLeft)) {
			foreach ($joinLeft AS $key => $value) {
				if($key && $value) {
					$where->joinLeft($key, $value, array());
				}
			}
		}
		
		if($groupBy) {
			$where->group($groupBy);
		}

		return $this->getAdapter()->fetchOne($where);
	}
	
	/**
     * Генерация уникального primary, когда primary имеет тип char или varchr
     *
     * @return string
     */
    public function getUniqPrimary() {
    	$primary = '';
    	$primary_length = 0;
    	
    	$info = $this->info();

    	if(isset($info['primary']) && $info['primary']) {
    		foreach ($info['primary'] AS $pr) {
    			$primary = $pr;
    			break;
    		}
    	}
    	
    	if(isset($info['metadata']) && $info['metadata'] && $primary) {
    		$primary_meta = isset($info['metadata'][$primary]) ? $info['metadata'][$primary] : null;
    		if($primary_meta) {
    			if(
					isset($primary_meta['DATA_TYPE']) && ($primary_meta['DATA_TYPE'] == 'char' || $primary_meta['DATA_TYPE'] == 'varchar') &&
					isset($primary_meta['LENGTH']) && $primary_meta['LENGTH'] && $primary_meta['PRIMARY']
				) {
					$primary_length = $primary_meta['LENGTH'];
    			}
    		}
    	}
    	
    	if($primary && $primary_length) {
    		$string = new Project_String;
    		
    		while(true) {
				$random_string = $string->getRandomString($primary_length);
				if(!count($this->find($random_string))) return $random_string; 
    		}
    	}
    	
    	return false;
    }
}
